﻿using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
using IdeaBlade.Aop;
using IdeaBlade.Core;
using IdeaBlade.EntityModel;
using IdeaBlade.Validation;

namespace SWTORLogDb.Entities
{
    /// <summary>
    /// Base class for Code First DevForce Entities
    /// </summary>
    [ProvideEntityAspect]
    [DataContract(IsReference = true)]
    public abstract class EntityBase
    {
        private EntityFacts _entityFacts;
        private EntityActions _entityActions;

        /// <summary>
        /// Get facts about this entity's current state.
        /// </summary>
        [NotMapped]
        [Bindable(false), Editable(false), Display(AutoGenerateField = false)]
        public EntityFacts EntityFacts
        {
            get { return _entityFacts ?? (_entityFacts = new EntityFacts(this)); }
        }

        [NotMapped]
        [Bindable(false), Editable(false), Display(AutoGenerateField = false)]
        public EntityActions EntityActions
        {
            get { return _entityActions ?? (_entityActions = new EntityActions(this)); }
        }

        /// <summary>
        /// Gets the row version.
        /// </summary>
        /// <value>
        /// The row version.
        /// </value>
        [DataMember]
        [Timestamp]
        [ConcurrencyCheck]
        [ConcurrencyStrategy(ConcurrencyStrategy.None)]
        [Display(AutoGenerateField = false)]
        public Byte[] RowVersion { get; internal set; }

        /// <summary>
        /// Perform custom validation of this entity and add errors to the <see cref="validationErrors"/>
        /// </summary>
        public virtual void Validate(VerifierResultCollection validationErrors) { }

        public virtual dynamic Copy()
        {
            throw new NotImplementedException("The Copy method is not implemented on type " + GetType());
        }

        public virtual dynamic CopyAttached()
        {
            EntityBase copiedEntity = this.Copy();
            EntityManager entityManager = EntityAspect.Wrap(this).EntityManager;
            if (entityManager == null) throw new NullReferenceException("EntityAspect.EntityManager cannot be null.");
            entityManager.AddEntity(copiedEntity);
            return copiedEntity;
        }

        /// <summary>
        /// Removes the white space from any string entity property on set.
        /// </summary>
        /// <param name="args">The args.</param>
        [BeforeSet]
        internal void TrimStrings(IEntityPropertySetInterceptorArgs args)
        {
            if (args.EntityProperty.DataType != typeof(string) || args.Value == null)
                return;

            args.Value = ((string)args.Value).Trim();
        }
    }
}
